package cn.yinzhiping.redislearn.framework;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * 实现分布式锁的步骤
 * 第一步：通过redis的setnx方式（不存在则设置）,往redis上设置一个带有过期时间的key，
 * 如果设置成功，则获得了分布式锁。这里设置过期时间，是防止在释放锁的时候出现异常导致锁释放不掉。
 *
 * 第二步：执行完业务操作之后，删除该锁。
 *
 * @author yinzhiping
 */
@Component
public class DistributedLock {
    @Autowired
    private StringRedisTemplate redisTemplate;
    /**
     * setIfAbsent方法，就是当键不存在的时候，设置，并且该方法可以设置键的过期时间。该方法对应到redis的原生命令就是：
     *
     * SET lockId content PX millisecond NX
     *
     * 获得锁
     */
    public boolean getLock(String lockId, long millisecond) {
        Boolean success = redisTemplate.opsForValue().setIfAbsent(lockId, "lock",
                millisecond, TimeUnit.MILLISECONDS);
        return success != null && success;
    }

    /**
     * 手动释放锁
     * @param lockId
     */
    public void releaseLock(String lockId) {
        redisTemplate.delete(lockId);
    }
}
